package com.hula.onion.book.server.utils;

import com.alibaba.fastjson.JSONObject;
import com.hula.onion.book.server.config.JedisUtils;
import com.hula.onion.book.server.config.SysConstants;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.CookieStore;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * Description:
 * Create Date:2018/1/25 16:17
 *
 * @author liangbing
 * @version 1.0
 */
public class CookieUtils {


    /**
     * 缓存cookie
     *
     * @param platformId
     * @param userFlag
     * @param cookieStore
     */
    public static void saveCookie(int platformId, String userFlag, CookieStore cookieStore) {

        List<Cookie> cookies = cookieStore.getCookies();

        if (cookies != null && cookies.size() > 0) {

            List<CookieCache> cacheList = new ArrayList<>();

            for (Cookie cookie : cookies) {

                CookieCache cookieCache = new CookieCache();

                cookieCache.setDomain(cookie.getDomain());
                cookieCache.setName(cookie.getName());
                cookieCache.setPath(cookie.getPath());
                cookieCache.setValue(cookie.getValue());

                cacheList.add(cookieCache);
            }

            //存入缓存
            String cookieCacheStr = JSONObject.toJSONString(cacheList);

            String key = SysConstants.REDIS_KEY_PRE + SysConstants.USER_COOKIE_KEY_PRE + platformId + ":" + userFlag;

            JedisUtils.getInstance().set(key, cookieCacheStr);
        }
    }

    /**
     * 从缓存中获取cookie设置到cookieStore
     *
     * @param platformId
     * @param userFlag
     * @param cookieStore
     */
    public static void setCookie(int platformId, String userFlag, CookieStore cookieStore) {

        //从缓存中获取
        String key = SysConstants.REDIS_KEY_PRE + SysConstants.USER_COOKIE_KEY_PRE + platformId + ":" + userFlag;

        String cookieCacheStr = JedisUtils.getInstance().get(key);

        if (!StringUtils.isEmpty(cookieCacheStr)) {

            List<CookieCache> cookieCacheList = JSONObject.parseArray(cookieCacheStr, CookieCache.class);

            if (cookieCacheList != null && cookieCacheList.size() > 0) {
                for (CookieCache cookieCache : cookieCacheList) {

                    BasicClientCookie c = new BasicClientCookie(cookieCache.getName(), cookieCache.getValue());

                    c.setDomain(cookieCache.getDomain());
                    c.setPath(cookieCache.getPath());

                    cookieStore.addCookie(c);
                }
            }
        }

    }

    public static List<BasicClientCookie> getCookieCache(int platformId, String userFlag) {
        //从缓存中获取
        String key = SysConstants.REDIS_KEY_PRE + SysConstants.USER_COOKIE_KEY_PRE + platformId + ":" + userFlag;
        String cookieCacheStr = JedisUtils.getInstance().get(key);
        if (StringUtils.isNotEmpty(cookieCacheStr)) {
            List<CookieCache> cookieCacheList = JSONObject.parseArray(cookieCacheStr, CookieCache.class);
            if (CollectionUtils.isEmpty(cookieCacheList)) {
                return Collections.emptyList();
            }
            List<BasicClientCookie> result = new ArrayList<>(cookieCacheList.size());
            for (CookieCache cookieCache : cookieCacheList) {
                BasicClientCookie basicClientCookie = new BasicClientCookie(cookieCache.getName(),
                        cookieCache.getValue());
                result.add(basicClientCookie);
            }
            return result;
        }
        return Collections.emptyList();
    }

    /**
     * turnHttpCookie2ApacheCookie
     *
     * @param cookie
     * @param domain
     * @param path
     * @return
     */
    public static Cookie turnHttpCookie2ApacheCookie(javax.servlet.http.Cookie cookie, String domain, String path) {

        BasicClientCookie apacheCookie = new BasicClientCookie(cookie.getName(), cookie.getValue());

        apacheCookie.setDomain(domain);
        apacheCookie.setPath(path);

        return apacheCookie;
    }

    /**
     * 把http client context中的cookie写入response
     *
     * @param clientContext
     * @param response
     */
    public static void writeCookieFromHttpClientContext(HttpClientContext clientContext, HttpServletResponse response) {

        //写cookies
        List<Cookie> cookies = clientContext.getCookieStore().getCookies();

        if (cookies != null && cookies.size() > 0) {
            for (Cookie cookie : cookies) {
                javax.servlet.http.Cookie httpCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
                response.addCookie(httpCookie);
            }
        }
    }

    /**
     * @param request
     * @param domain
     * @param path
     */
    public static void writeCookieFromRequest(BasicCookieStore cookieStore, HttpServletRequest request, String domain, String path) {

        javax.servlet.http.Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (javax.servlet.http.Cookie cookie : cookies) {
                org.apache.http.cookie.Cookie apacheCookie =
                        CookieUtils.turnHttpCookie2ApacheCookie(cookie, domain, path);
                cookieStore.addCookie(apacheCookie);
            }
        }
    }


    /**
     * Cookie Cache
     */
    private static class CookieCache {

        private String name;
        private String value;
        private String domain;
        private String path;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public String getDomain() {
            return domain;
        }

        public void setDomain(String domain) {
            this.domain = domain;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }
    }
}
